From 2c63bc60a890e617af2639ee4d95cc05006d7e1c Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Fri, 22 Oct 2010 15:14:51 +0100 Subject: [PATCH] libxc: convert memory op interface over to hypercall buffers Signed-off-by: Ian Campbell Signed-off-by: Ian Jackson --- tools/libxc/xc_domain.c | 82 ++++++++++++++++++++++------------------ tools/libxc/xc_private.c | 26 ++++++------- 2 files changed, 58 insertions(+), 50 deletions(-) diff --git a/tools/libxc/xc_domain.c b/tools/libxc/xc_domain.c index d0b15bcfe7..329735ebed 100644 --- a/tools/libxc/xc_domain.c +++ b/tools/libxc/xc_domain.c @@ -468,31 +468,30 @@ int xc_domain_set_memmap_limit(xc_interface *xch, unsigned long map_limitkb) { int rc; - struct xen_foreign_memory_map fmap = { .domid = domid, .map = { .nr_entries = 1 } }; + DECLARE_HYPERCALL_BUFFER(struct e820entry, e820); - struct e820entry e820 = { - .addr = 0, - .size = (uint64_t)map_limitkb << 10, - .type = E820_RAM - }; - - set_xen_guest_handle(fmap.map.buffer, &e820); + e820 = xc_hypercall_buffer_alloc(xch, e820, sizeof(*e820)); - if ( lock_pages(xch, &e820, sizeof(e820)) ) + if ( e820 == NULL ) { - PERROR("Could not lock memory for Xen hypercall"); - rc = -1; - goto out; + PERROR("Could not allocate memory for xc_domain_set_memmap_limit hypercall"); + return -1; } + e820->addr = 0; + e820->size = (uint64_t)map_limitkb << 10; + e820->type = E820_RAM; + + xc_set_xen_guest_handle(fmap.map.buffer, e820); + rc = do_memory_op(xch, XENMEM_set_memory_map, &fmap, sizeof(fmap)); - out: - unlock_pages(xch, &e820, sizeof(e820)); + xc_hypercall_buffer_free(xch, e820); + return rc; } #else @@ -587,6 +586,7 @@ int xc_domain_increase_reservation(xc_interface *xch, xen_pfn_t *extent_start) { int err; + DECLARE_HYPERCALL_BOUNCE(extent_start, nr_extents * sizeof(*extent_start), XC_HYPERCALL_BUFFER_BOUNCE_BOTH); struct xen_memory_reservation reservation = { .nr_extents = nr_extents, .extent_order = extent_order, @@ -595,18 +595,17 @@ int xc_domain_increase_reservation(xc_interface *xch, }; /* may be NULL */ - if ( extent_start && lock_pages(xch, extent_start, nr_extents * sizeof(xen_pfn_t)) != 0 ) + if ( xc_hypercall_bounce_pre(xch, extent_start) ) { - PERROR("Could not lock memory for XENMEM_increase_reservation hypercall"); + PERROR("Could not bounce memory for XENMEM_increase_reservation hypercall"); return -1; } - set_xen_guest_handle(reservation.extent_start, extent_start); + xc_set_xen_guest_handle(reservation.extent_start, extent_start); err = do_memory_op(xch, XENMEM_increase_reservation, &reservation, sizeof(reservation)); - if ( extent_start ) - unlock_pages(xch, extent_start, nr_extents * sizeof(xen_pfn_t)); + xc_hypercall_bounce_post(xch, extent_start); return err; } @@ -645,6 +644,7 @@ int xc_domain_decrease_reservation(xc_interface *xch, xen_pfn_t *extent_start) { int err; + DECLARE_HYPERCALL_BOUNCE(extent_start, nr_extents * sizeof(*extent_start), XC_HYPERCALL_BUFFER_BOUNCE_BOTH); struct xen_memory_reservation reservation = { .nr_extents = nr_extents, .extent_order = extent_order, @@ -652,12 +652,6 @@ int xc_domain_decrease_reservation(xc_interface *xch, .domid = domid }; - if ( lock_pages(xch, extent_start, nr_extents * sizeof(xen_pfn_t)) != 0 ) - { - PERROR("Could not lock memory for XENMEM_decrease_reservation hypercall"); - return -1; - } - if ( extent_start == NULL ) { DPRINTF("decrease_reservation extent_start is NULL!\n"); @@ -665,11 +659,16 @@ int xc_domain_decrease_reservation(xc_interface *xch, return -1; } - set_xen_guest_handle(reservation.extent_start, extent_start); + if ( xc_hypercall_bounce_pre(xch, extent_start) ) + { + PERROR("Could not bounce memory for XENMEM_decrease_reservation hypercall"); + return -1; + } + xc_set_xen_guest_handle(reservation.extent_start, extent_start); err = do_memory_op(xch, XENMEM_decrease_reservation, &reservation, sizeof(reservation)); - unlock_pages(xch, extent_start, nr_extents * sizeof(xen_pfn_t)); + xc_hypercall_bounce_post(xch, extent_start); return err; } @@ -722,6 +721,7 @@ int xc_domain_populate_physmap(xc_interface *xch, xen_pfn_t *extent_start) { int err; + DECLARE_HYPERCALL_BOUNCE(extent_start, nr_extents * sizeof(*extent_start), XC_HYPERCALL_BUFFER_BOUNCE_BOTH); struct xen_memory_reservation reservation = { .nr_extents = nr_extents, .extent_order = extent_order, @@ -729,18 +729,16 @@ int xc_domain_populate_physmap(xc_interface *xch, .domid = domid }; - if ( lock_pages(xch, extent_start, nr_extents * sizeof(xen_pfn_t)) != 0 ) + if ( xc_hypercall_bounce_pre(xch, extent_start) ) { - PERROR("Could not lock memory for XENMEM_populate_physmap hypercall"); + PERROR("Could not bounce memory for XENMEM_populate_physmap hypercall"); return -1; } - - set_xen_guest_handle(reservation.extent_start, extent_start); + xc_set_xen_guest_handle(reservation.extent_start, extent_start); err = do_memory_op(xch, XENMEM_populate_physmap, &reservation, sizeof(reservation)); - unlock_pages(xch, extent_start, nr_extents * sizeof(xen_pfn_t)); - + xc_hypercall_bounce_post(xch, extent_start); return err; } @@ -778,8 +776,9 @@ int xc_domain_memory_exchange_pages(xc_interface *xch, unsigned int out_order, xen_pfn_t *out_extents) { - int rc; - + int rc = -1; + DECLARE_HYPERCALL_BOUNCE(in_extents, nr_in_extents*sizeof(*in_extents), XC_HYPERCALL_BUFFER_BOUNCE_IN); + DECLARE_HYPERCALL_BOUNCE(out_extents, nr_out_extents*sizeof(*out_extents), XC_HYPERCALL_BUFFER_BOUNCE_OUT); struct xen_memory_exchange exchange = { .in = { .nr_extents = nr_in_extents, @@ -792,11 +791,20 @@ int xc_domain_memory_exchange_pages(xc_interface *xch, .domid = domid } }; - set_xen_guest_handle(exchange.in.extent_start, in_extents); - set_xen_guest_handle(exchange.out.extent_start, out_extents); + + if ( xc_hypercall_bounce_pre(xch, in_extents) || + xc_hypercall_bounce_pre(xch, out_extents)) + goto out; + + xc_set_xen_guest_handle(exchange.in.extent_start, in_extents); + xc_set_xen_guest_handle(exchange.out.extent_start, out_extents); rc = do_memory_op(xch, XENMEM_exchange, &exchange, sizeof(exchange)); +out: + xc_hypercall_bounce_post(xch, in_extents); + xc_hypercall_bounce_post(xch, out_extents); + return rc; } diff --git a/tools/libxc/xc_private.c b/tools/libxc/xc_private.c index 2ef31f0827..2b9628a065 100644 --- a/tools/libxc/xc_private.c +++ b/tools/libxc/xc_private.c @@ -428,23 +428,22 @@ int xc_flush_mmu_updates(xc_interface *xch, struct xc_mmu *mmu) int do_memory_op(xc_interface *xch, int cmd, void *arg, size_t len) { DECLARE_HYPERCALL; + DECLARE_HYPERCALL_BOUNCE(arg, len, XC_HYPERCALL_BUFFER_BOUNCE_BOTH); long ret = -EINVAL; - hypercall.op = __HYPERVISOR_memory_op; - hypercall.arg[0] = (unsigned long)cmd; - hypercall.arg[1] = (unsigned long)arg; - - if ( len && lock_pages(xch, arg, len) != 0 ) + if ( xc_hypercall_bounce_pre(xch, arg) ) { - PERROR("Could not lock memory for XENMEM hypercall"); + PERROR("Could not bounce memory for XENMEM hypercall"); goto out1; } - ret = do_xen_hypercall(xch, &hypercall); + hypercall.op = __HYPERVISOR_memory_op; + hypercall.arg[0] = (unsigned long) cmd; + hypercall.arg[1] = HYPERCALL_BUFFER_AS_ARG(arg); - if ( len ) - unlock_pages(xch, arg, len); + ret = do_xen_hypercall(xch, &hypercall); + xc_hypercall_bounce_post(xch, arg); out1: return ret; } @@ -474,24 +473,25 @@ int xc_machphys_mfn_list(xc_interface *xch, xen_pfn_t *extent_start) { int rc; + DECLARE_HYPERCALL_BOUNCE(extent_start, max_extents * sizeof(xen_pfn_t), XC_HYPERCALL_BUFFER_BOUNCE_OUT); struct xen_machphys_mfn_list xmml = { .max_extents = max_extents, }; - if ( lock_pages(xch, extent_start, max_extents * sizeof(xen_pfn_t)) != 0 ) + if ( xc_hypercall_bounce_pre(xch, extent_start) ) { - PERROR("Could not lock memory for XENMEM_machphys_mfn_list hypercall"); + PERROR("Could not bounce memory for XENMEM_machphys_mfn_list hypercall"); return -1; } - set_xen_guest_handle(xmml.extent_start, extent_start); + xc_set_xen_guest_handle(xmml.extent_start, extent_start); rc = do_memory_op(xch, XENMEM_machphys_mfn_list, &xmml, sizeof(xmml)); if (rc || xmml.nr_extents != max_extents) rc = -1; else rc = 0; - unlock_pages(xch, extent_start, max_extents * sizeof(xen_pfn_t)); + xc_hypercall_bounce_post(xch, extent_start); return rc; } -- 2.30.2